﻿//CsvStrategyReport.cs
//Copyright (c) 2013 StockSharp LLC, all rights reserved.
//This code module is part of StockSharp library.
//This code is licensed under the GNU GENERAL PUBLIC LICENSE Version 3.
//See the file License.txt for the license details.
//More info on: http://stocksharp.com

namespace StockSharp.Algo.Reporting
{
	using System;
	using System.Globalization;
	using System.IO;
	using System.Linq;

	using Ecng.Collections;
	using Ecng.Common;

	using StockSharp.Algo.Strategies;

	///<summary>
	/// Генератор отчета по эквити стратегии в формате Csv.
	///</summary>
	public class CsvStrategyReport : StrategyReport
	{
		private readonly string _separator = CultureInfo.CurrentCulture.TextInfo.ListSeparator;

		/// <summary>
		/// Создать генератор Csv отчетов.
		/// </summary>
		/// <param name="strategy">Стратегия, для которой необходимо сгенерировать отчет.</param>
		/// <param name="fileName">Название файла, в котором сгенерируется отчет в формате Csv.</param>
		public CsvStrategyReport(Strategy strategy, string fileName)
			: base(strategy)
		{
			if (fileName.IsEmpty())
				throw new ArgumentNullException("fileName");

			FileName = fileName;
		}

		/// <summary>
		/// Название файла, в котором сгенерируется отчет.
		/// </summary>
		public string FileName { get; private set; }

		/// <summary>
		/// Сгенерировать отчет в формате Csv.
		/// </summary>
		public override void Generate()
		{
			using (var writer = new StreamWriter(FileName))
			{
				WriteValues(writer, "Стратегия", "Инструмент", "Портфель", "Общее время работы", "Позиция", "P&L", "Комиссия", "Проскальзывание", "Задержка");
				WriteValues(writer,
					Strategy.Name, Strategy.Security.Id, Strategy.Portfolio.Name, Strategy.TotalWorkingTime,
					Strategy.Position, Strategy.PnL, Strategy.Commission, Strategy.Slippage, Strategy.Latency);

				var parameters = Strategy.Parameters.SyncGet(c => c.ToArray());
				WriteValues(writer, "Параметры стратегии");
				WriteValues(writer, parameters.Select(p => (object)p.Name).ToArray());
				WriteValues(writer, parameters.Select(p => p.Value is TimeSpan ? Format((TimeSpan)p.Value) : p.Value).ToArray());

				var statParameters = Strategy.StatisticManager.Parameters.SyncGet(c => c.ToArray());
				WriteValues(writer, "Статистика");
				WriteValues(writer, statParameters.Select(p => (object)p.Name).ToArray());
				WriteValues(writer, statParameters.Select(p => p.Value is TimeSpan ? Format((TimeSpan)p.Value) : p.Value).ToArray());
				
				WriteValues(writer, "Заявки");
				WriteValues(writer, "Номер заявки", "Номер транзакции", "Направление", "Время", "Цена", "Цена (усредн.)", "Статус", "Состояние", "Баланс",
					"Объем", "Тип", "Проскальзывание", "Задержка регистрации", "Задержка отмены");

				foreach (var order in Strategy.Orders)
				{
					WriteValues(writer, order.Id, order.TransactionId, Format(order.Direction), order.Time, order.Price, order.GetAveragePrice(),
						Format(order.State), order.IsMatched() ? "Исполнена" : (order.IsCanceled() ? "Отменена" : string.Empty), order.Balance,
						order.Volume, Format(order.Type), Strategy.SlippageManager.GetSlippage(order), Format(order.LatencyRegistration), Format(order.LatencyCancellation));
				}

				WriteValues(writer, "Сделки");
				WriteValues(writer, "Номер сделки", "Номер транзакции", "Время", "Цена", "Объем", "Направление", "Номер заявки", "Прибыль",
					"Проскальзывание", "Проскальзывание (котирование)");

				foreach (var trade in Strategy.MyTrades)
				{
					WriteValues(writer, trade.Trade.Id, trade.Order.TransactionId, Format(trade.Trade.Time), trade.Trade.Price, trade.Trade.Volume,
						Format(trade.Order.Direction), trade.Order.Id, Strategy.PnLManager.ProcessMyTrade(trade).PnL, trade.GetSlippage(), Strategy.SlippageManager.GetSlippage(trade));
				}
			}
		}

		private void WriteValues(TextWriter writer, params object[] values)
		{
			for (var i = 0; i < values.Length; i++)
			{
				var value = values[i];

				if (value is DateTime)
					value = Format((DateTime)value);
				else if (value is TimeSpan)
					value = Format((TimeSpan)value);

				writer.Write(value);

				if (i < (values.Length - 1))
					writer.Write(_separator);
			}

			writer.WriteLine();
		}

		//private void Save()
		//{



		//    using (var sw = new StreamWriter(FileName))
		//    {
		//        sw.WriteLine("; All Trades; Long Trades; Short Trades");

		//        sw.WriteLine("Net Profit; " + _strategyStatistics.NetProfit + "; " + _strategyStatistics.NetLongProfit +
		//                     "; " + _strategyStatistics.NetShortProfit);
		//        sw.WriteLine("Number of Trades; " + _strategyStatistics.NumberOfTrades + "; " +
		//                     _strategyStatistics.NumberOfLongTrades + "; " +
		//                     _strategyStatistics.NumberOfShortTrades);
		//        sw.WriteLine("Average Profit; " + _strategyStatistics.AverageProfit + "; " +
		//                     _strategyStatistics.AverageLongProfit + "; " + _strategyStatistics.AverageShortProfit);
		//        sw.WriteLine("Average Profit %; " + _strategyStatistics.AverageNetProfitPrc + "%; " +
		//                     _strategyStatistics.AverageLongNetProfitPrc + "%; " +
		//                     _strategyStatistics.AverageShortNetProfitPrc + "%");
		//        sw.WriteLine(";;;");
		//        sw.WriteLine("Winning Trades; " + _strategyStatistics.WinningTrades + "; " +
		//                     _strategyStatistics.WinningLongTrades + "; " + _strategyStatistics.LosingLongTrades);
		//        sw.WriteLine("Win Rate; " + _strategyStatistics.WinRate + "%; " + _strategyStatistics.WinLongRate + "%; " +
		//                     _strategyStatistics.WinShortRate + "%");
		//        sw.WriteLine("Gross Profit; " + _strategyStatistics.GrossProfit + "; " + _strategyStatistics.GrossLongProfit +
		//                     "; " + _strategyStatistics.GrossShortProfit);
		//        sw.WriteLine("Average Profit; " + _strategyStatistics.AverageWinProfit + "; " +
		//                     _strategyStatistics.AverageWinLongProfit + "; " +
		//                     _strategyStatistics.AverageWinShortProfit);
		//        sw.WriteLine("Average Profit %; " + _strategyStatistics.AverageWinProfitPrc + "%; " +
		//                     _strategyStatistics.AverageWinLongProfitPrc + "%; " +
		//                     _strategyStatistics.AverageWinShortProfitPrc + "%");
		//        sw.WriteLine(";;;");
		//        sw.WriteLine("Losing Trades; " + _strategyStatistics.LosingTrades + "; " +
		//                     _strategyStatistics.LosingLongTrades + "; " + _strategyStatistics.LosingShortTrades);
		//        sw.WriteLine("Loss Rate; " + _strategyStatistics.LossRate + "%; " + _strategyStatistics.LossLongRate + "%; " +
		//                     _strategyStatistics.LossShortRate + "%");
		//        sw.WriteLine("Gross Loss; " + _strategyStatistics.GrossLoss + "; " + _strategyStatistics.GrossLongLoss +
		//                     "; " + _strategyStatistics.GrossShortLoss);
		//        sw.WriteLine("Average Loss; " + _strategyStatistics.AverageLoss + "; " + _strategyStatistics.AverageLongLoss +
		//                     "; " + _strategyStatistics.AverageShortLoss);
		//        sw.WriteLine("Average Loss %; " + _strategyStatistics.AverageLossPrc + "%; " +
		//                     _strategyStatistics.AverageLongLossPrc + "%; " +
		//                     _strategyStatistics.AverageShortLossPrc + "%");
		//        sw.WriteLine(";;;");
		//        sw.WriteLine("Maximum Drawdown; " + _strategyStatistics.MaxDrawdown + "; " +
		//                     _strategyStatistics.MaxLongDrawdown + "; " + _strategyStatistics.MaxShortDrawdown);
		//        sw.WriteLine("Profit Factor; " + _strategyStatistics.ProfitFactor + "; " +
		//                     _strategyStatistics.ProfitFactorLong + "; " + _strategyStatistics.ProfitFactorShort);
		//        sw.WriteLine("Recovery Factor; " + _strategyStatistics.RecoveryFactor + "; " +
		//                     _strategyStatistics.RecoveryFactorLong + "; " +
		//                     _strategyStatistics.RecoveryFactorShort);
		//        sw.WriteLine("Payoff Ratio; " + _strategyStatistics.PayoffRatio + "; " + _strategyStatistics.PayoffRatioLong +
		//                     "; " + _strategyStatistics.PayoffRatioShort);
		//        sw.WriteLine("Smoothness Factor; " + _strategyStatistics.SmoothnessFactor);

		//        sw.WriteLine(";;;");
		//        sw.WriteLine(";;;");
		//        sw.WriteLine(";;;");

		//        var index = 0;
		//        sw.WriteLine(
		//            "Position; Quantity; Entry Date; Entry Price; Exit Date; Exit Price; Equity; Long; Short; Median;");
		//        foreach (var kvp in _strategyStatistics.TradePairs)
		//        {
		//            sw.WriteLine(
		//                kvp.Value.FirstTrade.OrderDirection + ";" +
		//                kvp.Value.FirstTrade.Volume + ";" +
		//                kvp.Value.FirstTrade.Time + ";" +
		//                kvp.Value.FirstTrade.Price + ";" +
		//                kvp.Value.SecondTrade.Time + ";" +
		//                kvp.Value.SecondTrade.Price + ";" +
		//                _strategyStatistics.Equity[index] + ";" +
		//                _strategyStatistics.LongEquity[index] + ";" +
		//                _strategyStatistics.ShortEquity[index] + ";" +
		//                _strategyStatistics.EquityMedian[index]);
		//            index++;
		//        }
		//    }
		//}
	}
}